home *** CD-ROM | disk | FTP | other *** search
- unit CommonStuff;
-
- {$ifdef Ver100} { Delphi 3.0x }
- {$define DelphiLessThan4}
- {$endif}
- {$ifdef Ver110} { C++ Builder 3.0x }
- {$define DelphiLessThan4}
- {$endif}
-
- interface
-
- uses
- Menus, ComCtrls, ExtCtrls, Classes, Forms, Registry, SysUtils;
-
- type
- TIvoryHacker = class(TObject)
- public
- FInitialised: Boolean;
- FTabControl: TTabControl; //Component palette
- FPalettePopup: TPopupMenu; //Palette popup menu
- {$ifndef DelphiLessThan4}
- FControlBar: TControlBar; //Delphi's main window's control bar
- {$endif}
- FOptions: TMenuItem; //Archaeopteryx options menu item
- Ini: TRegIniFile; //Used to save and restore options in registry
- procedure DoAbout(Sender: TObject); //Shows About box
- procedure AddOptionsItem; //Ensures Options item exists
- constructor Create;
- destructor Destroy; override;
- procedure Setup;
- procedure TidyUp;
- end;
-
- var
- Stuff: TIvoryHacker;
-
- //Locate a requested component object
- function GetComponent(Owner: TComponent; const Name, Error: String): TComponent;
-
- //Warn user if an event that we chain is already chained
- procedure TestChainedEventHandler(OldHandler, NewHandler: Pointer);
-
- procedure Register;
-
- resourcestring
- SSetupError = 'An error occurred in customising the IDE';
- SGenericError = 'Cannot find requested component: ';
- SAbout = '&About Archaeopteryx...';
-
- const
- {$ifdef DelphiLessThan4}
- SRegSection = 'Archaeopteryx';
- {$else}
- SRegSection = '4.0';
- {$endif}
-
- implementation
-
- uses
- Dialogs, Windows, Controls;
-
- {$R Bitmap.Res}
-
- resourcestring
- SOptions = '&Options';
- {$ifndef DelphiLessThan4}
- STabControlBar = 'ControlBar1'; //Component palette's control bar
- {$endif}
- SAboutCaption = 'About Archaeopteryx';
- SAboutMsg = 'Archaeopteryx.'#13#13 +
- 'Archaeopteryx (ahr-kee-ahp-tur-iks) is a prehistoric piece of' +
- 'software, dug out of the ground and restored by Oblong, ⌐ 1997.'#13#13 +
- 'This is freeware by the way - everyone''s doin'' it!'#13#13 +
- 'The source code for the Delphi 3 version of this ' +
- 'package accompanies an article on IDE customising in'#13 +
- 'The Delphi Magazine in November, 1997 (Issue 27)'#13#13;
- SChainingWarning = 'IMPORTANT INFORMATION!!!'#13#13+
- 'The Archaeopteryx package has modified part of Delphi''s internals ' +
- 'in order to operate effectively. However it appears that another ' +
- 'add-in package has also done a similar POTENTIALLY conflicting ' +
- 'modification.'#13#13 +
- 'In order to avoid the POSSIBLE problems when removing your ' +
- 'add-in packages, ensure Archaeopteryx is uninstalled before ' +
- 'any of your previously installed packages.'#13#13 +
- 'Alternatively, uninstall Archaeopteryx now, followed by all ' +
- 'the other add-in packages and then re-install Archaeopteryx ' +
- 'first, followed by all the others'#13#13'Thank you';
-
- const
- SPaletteMenu = 'PaletteMenu'; //Component palette popup menu
- STabControl = 'TabControl'; //Component palette
- SIconName = 'Archaeopteryx'; //My Archaeopteryx icon resource
- SImage = 'Image'; //Name of picture component on a message dialog
- //Registry strings
- SRegWarning = 'Warning';
- {$ifdef DelphiLessThan4}
- SRegPath = 'Software\Oblong\';
- {$else}
- SRegPath = 'Software\Oblong\Archaeopteryx';
- {$endif}
-
- //Locates a component on the given Owner whose name matches that passed in
- //If the component cannot be found, an exception is raised with the string Error
- //unless RaiseExcept is False
- function GetComponent(Owner: TComponent; const Name, Error: String): TComponent;
- begin
- Result := Owner.FindComponent(Name);
- if not Assigned(Result) then
- raise Exception.Create(Error);
- end;
-
- procedure TestChainedEventHandler(OldHandler, NewHandler: Pointer);
- begin
- //If the original (as designed) handler and
- //the current handler of an event are not the same,
- //then report the error to the user the first time
- if (OldHandler <> NewHandler) and
- Stuff.Ini.ReadBool(SRegSection, SRegWarning, True) then
- begin
- MessageDlg(SChainingWarning, mtWarning, [mbOk], 0);
- //Set registry flag so the error is not reported again
- Stuff.Ini.WriteBool(SRegSection, SRegWarning, False)
- end
- end;
-
- constructor TIvoryHacker.Create;
- begin
- inherited Create;
- end;
-
- destructor TIvoryHacker.Destroy;
- begin
- TidyUp;
- inherited Destroy
- end;
-
- procedure TIvoryHacker.Setup;
- begin
- //For registry access
- Ini := TRegIniFile.Create(SRegPath);
- //Locate various IDE components
- FTabControl := GetComponent(Application.MainForm, STabControl, SGenericError + STabControl) as TTabControl;
- FPalettePopup := GetComponent(Application.MainForm, SPaletteMenu, SGenericError + SPaletteMenu) as TPopupMenu;
- {$ifndef DelphiLessThan4}
- FControlBar := GetComponent(Application.MainForm, STabControlBar, SGenericError + STabControlBar) as TControlBar;
- {$endif}
- Stuff.FInitialised := True
- end;
-
- procedure TIvoryHacker.TidyUp;
- begin
- //Get rid of registry object
- Ini.Free;
- //If someone made an options menu, then get rid of it
- FOptions.Free;
- end;
-
- procedure TIvoryHacker.DoAbout(Sender: TObject);
-
- //Code to extract program version and file
- //version from the current binary file
- function VersionNumber: String;
- var
- VerInfo: Pointer;
- Len, BufSize: {$ifdef DelphiLessThan4}Integer{$else}Cardinal{$endif};
- Dest: PChar;
- DestCodeInfo: ^LongRec;
- LangCharSet: String;
- FileName: array[0..Max_Path] of Char;
- begin
- Result := '';
- //Find current binary file name
- GetModuleFileName(HInstance, FileName, Max_Path);
- //How big is version info?
- BufSize := GetFileVersionInfoSize(FileName, Len);
- if BufSize > 0 then
- begin
- //Reserve sufficient memory
- GetMem(VerInfo, BufSize);
- try
- //Get version information
- if GetFileVersionInfo(FileName, 0, BufSize, VerInfo) then
- begin
- //Get translation table
- if VerQueryValue(VerInfo, '\VarFileInfo\Translation', Pointer(DestCodeInfo), Len) and
- (Len >= 4) then { Translation table exists}
- LangCharSet := Format('\StringFileInfo\%.4x%.4x\', [DestCodeInfo^.Lo, DestCodeInfo^.Hi]);
- //Get ver. info. value via translation table
- if VerQueryValue(VerInfo, PChar(LangCharSet + 'ProductVersion'), Pointer(Dest), Len) then
- AppendStr(Result, 'Version ' + StrPas(Dest));
- //Get ver. info. value via translation table
- if VerQueryValue(VerInfo, PChar(LangCharSet + 'FileVersion'), Pointer(Dest), Len) then
- AppendStr(Result, ' (Build ' + StrPas(Dest) + ')');
- end
- finally
- //Free sufficient memory
- FreeMem(VerInfo, BufSize);
- end
- end
- end;
-
- begin
- //Would normally use MessageDlg, but I
- //want to customise the icon, so use
- //the more primitive CreateMessageDialog
- with CreateMessageDialog(SAboutMsg + VersionNumber, mtInformation, [mbOk]) do
- try
- (FindComponent(SImage) as TImage).Picture.Icon.Handle :=
- LoadIcon(HInstance, PChar(SIconName));
- Caption := SAboutCaption;
- ShowModal;
- finally
- Free
- end;
- end;
-
- procedure TIvoryHacker.AddOptionsItem;
- begin
- if not FInitialised then
- Setup;
- //If another unit needs to add options items,
- //they call this to add the main Options sub-menu
- //just above the last menu item (Properties)
- if not Assigned(FOptions) then
- begin
- FOptions := NewItem(SOptions, 0, False, True, nil, 0, '');
- FPalettePopup.Items.Add(FOptions);
- FOptions.MenuIndex := FPalettePopup.Items.Count - 1;
- end;
- end;
-
- procedure Register;
- begin
- if not Stuff.FInitialised then
- Stuff.Setup;
- end;
-
- initialization
- try
- Stuff := TIvoryHacker.Create
- except
- on E: Exception do
- ShowMessage(SSetupError + ': ' + E.Message)
- end
- finalization
- Stuff.Free;
- end.
-